import datetime

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView

from common.http_util import Result


def to_list(request):
        print("=========== 请求进入到了XXX_list.html ==========")
        return render(request, 'demo/XXX_list.html')


def to_user_list(request):
    print("=========== 请求进入到了user_list.html ==========")
    return render(request, 'demo/u_list.html')

from common.db_util import MySqlDb

'''查询用户列表'''
class UserList(APIView):

    def get(self, request):
        print("=========== 进入到了UserList ==========")
        #请求参数
        params = request.GET.dict()
        print("请求参数：",params)
        #查询出全部的用户
        sql = "SELECT * FROM sys_user where 1=1"
        condition = ""
        #用户名称
        username = params.get("username")
        if username:
            condition += f" and username like '%{username}%'"
        #用户昵称
        nickname = params.get("nickname")
        #用户状态
        status = params.get("status")
        if status:
            status = int(status)
            if status == -1:
                condition += " and status in (0,1)"
            else:
                condition += " and status = :status"

        #拼接sql语句
        if condition:
            sql += condition
        #默认查询出用户
        list = MySqlDb.query(sql,params=params)
        for item in list:
            item["password"] =""
        return Response(Result(data=list))

from blog.models import User
class Bak_UserModify(APIView):
    def post(self, request):
        print("=========== 进入到了UserModify ==========")
        #请求参数
        params = request.data
        print("请求参数：",params)
        #更新sql语句
        sql = "update sys_user "
        set_buffer = ""
        for key,value in params.items():
            if value:
                if key == "user_id":
                    continue
                set_buffer += f"{key}='{value}',"
        if set_buffer:
           #去掉最后一个逗号
           # set_buffer = set_buffer[:-1]
           #增加update_time字段更新
           set_buffer += " update_time=now()"
           sql = f"update sys_user set {set_buffer} where user_id=:user_id"
           # 更新用户
           count = MySqlDb.update(sql, params=params)
        else:
            count = 0
        return Response(Result(data=count))

class UserModify(APIView):
    def post(self, request):
        print("=========== 进入到了UserModify ==========")
        session = None
        try:
            #请求参数
            params = request.data
            print("请求参数：",params)
            session = MySqlDb.get_mysql_session()
            user:User = session.query(User).filter(User.id==params.get("id")).first()
            if user:
                user.username = params.get("username")
                if params.get("password"):
                    user.password = params.get("password")
                user.real_name = params.get("real_name")
                user.email = params.get("email")
                user.phone = params.get("phone")
                user.status = params.get("status")
                user.is_admin = params.get("is_admin")
                user.job_name = params.get("job_name")
                user.remark = params.get("remark")
                user.update_time = datetime.datetime.now()
                session.commit()
                return Response(Result(data=1))
            else:
                return Response(Result(code=444,msg="更新失败！",data=0))
        except Exception as e:
            print(e)
            if session:
                session.rollback()  # 添加回滚操作
            return Response(Result(code=444,msg="更新失败！==>"+e.__str__(),data=0))
        finally:
            if session:
                session.close()  # 确保会话总是被关闭

class UserAdd(APIView):
    def post(self, request):
        print("=========== 进入到了UserAdd ==========")
        #请求参数
        params = request.data
        """#对应字段如下：
            username,password,real_name,email,phone,status,is_admin,update_time,job_name,remark
        """
        try:
            print("请求参数：",params)
            user:User= User()
            user.username = params.get("username")
            user.password = params.get("password")
            user.real_name = params.get("real_name")
            user.email = params.get("email")
            user.phone = int(params.get("phone"))
            user.status = params.get("status")
            user.is_admin = params.get("is_admin")
            user.job_name = params.get("job_name")
            user.remark = params.get("remark")
            user.update_time = datetime.datetime.now()
            user.create_time = datetime.datetime.now()
            result= MySqlDb.insert_by_model(user)
            if result:
                return Response(Result(data=result))
            else:
                return Response(Result(code=444,msg="添加失败！",data=False))
        except Exception as e:
            print(e)
            return Response(Result(code=444,msg="添加失败！==>"+e.__str__(),data=False))


'''删除用户'''
class UserDelete(APIView):
    def get(self, request):
        print("=========== 进入到了UserDelete ==========")
        # 请求参数
        params = request.GET.dict()
        print("请求参数：", params)
        # 删除sql语句
        sql = "delete from sys_user where id=:id"
        count:int = MySqlDb.delete(sql, params=params)
        if count > 0:
            return Response(Result(data=count))
        else:
            return Response(Result(code=444, msg="删除失败！", data=0))

'''批量删除用户'''
class UserBatchDelete(APIView):
    def post(self, request):
        print("=========== 进入到了UserBatchDelete ==========")
        #请求参数
        params = request.data
        print("请求参数：",params)
        ids = params.get("ids")
        if ids:
            #转换成字串
            ids_str=""
            for item in ids:
                item = str(item)
                ids_str += f"{item},"

            #去掉最后一个逗号
            if ids_str.endswith(","):
                ids_str = ids_str[:-1]

            sql = "delete from sys_user where id in ("+ids_str+")"
            print("删除sql语句：",sql)
            count:int = MySqlDb.delete(sql, params=params)
            if count > 0:
                return Response(Result(data=count))
            else:
                return Response(Result(code=444, msg="删除失败！", data=0))

'''组装角色树'''
class UserRoleSelectTree(APIView):
    def get(self, request):
        print("=========== 进入到了RoleSelectTree ==========")
        # 请求参数
        params = request.GET.dict()
        print("请求参数：", params)
        #查询出所有的角色
        sql = "select * from sys_role where status=1"
        list = MySqlDb.query(sql, params=params)
        """组装角色列表"""
        role_tree=[]
        for item in list:
            role_tree.append({"id":item["id"],"label":item["role_name"],"expanded":True,"checked":False})
        """计算是否存在已授权情况"""
        user_id = params.get("user_id")
        temp_user_role_dict = {}
        if user_id:
            #查询出用户的角色
            sql = "select role_id from sys_user_role where user_id=:user_id"
            user_role_list = MySqlDb.query(sql, params=params)
            for item in user_role_list:
                temp_user_role_dict[item["role_id"]]=item["role_id"]

        #计算是否存在已授权情况
        for item in role_tree:
            role_id = item["id"]
            if role_id in temp_user_role_dict:
                item["checked"]=True
            else:
                item["checked"]=False

        return Response(Result(data=role_tree))

"""更新或追加用户授权角色"""
class UserRoleUpdate(APIView):
    def post(self, request):
            print("=========== 进入到了UserRoleUpdate ==========")
            # 请求参数
            params = request.data
            print("请求参数：", params)
            user_id = params.get("user_id")
            #获取角色列表
            role_ids = params.get("role_ids")


            #删除用户的角色
            sql = "delete from sys_user_role where user_id=:user_id"
            MySqlDb.delete(sql, params=params)
            #添加用户的角色
            for role_id in role_ids:
                userRole:UserRole = UserRole()
                userRole.user_id = user_id
                userRole.role_id = role_id
                userRole.create_time = datetime.datetime.now()
                MySqlDb.insert_by_model(userRole)

            return Response(Result(data=1))




def to_menu_tree(request):
    print("=========== 请求进入到了menu_tree.html ==========")
    return render(request, 'demo/menu_tree.html')


from blog.models import *
'''菜单列表'''
class MenuList(APIView):
    def get(self, request):
        print("=========== 进入到了MenuList ==========")
        # 请求参数
        params = request.GET.dict()
        print("请求参数：", params)
        #根据系统ID查询菜单列表
        sql = "select * from sys_menu sm where sm.status=1 and system_id =:system_id order by sort asc"
        list = MySqlDb.query(sql, params=params)
        #散列成字典
        menu_dict = {}
        for item in list:
            menu_dict[item["id"]] = item
        #组装树形结构
        menu_tree = []
        for item in list:
            #如果父菜单ID为0，说明是根菜单
            if item["parent_id"] == 0:
                menu_tree.append(item)
            else:
                #如果父菜单ID不为0，说明是子菜单
                parent_menu = menu_dict[item["parent_id"]]
                #子菜单不存在时，创建一个空列表
                if "children" not in parent_menu:
                    parent_menu["children"] = []
                #把子菜单添加到父菜单的children列表中
                parent_menu["children"].append(item)
        return Response(Result(data=menu_tree))

'''查询菜单挂载树'''
class MenuSelectTree(APIView):
    def get(self, request):
        print("=========== 进入到了MenuTree ==========")
        # 请求参数
        params = request.GET.dict()
        print("请求参数：", params)
        #取出系统ID
        system_id = params.get("system_id")
        #查询出所有的菜单
        sql = "select * from sys_menu sm where sm.is_leaf=0 and sm.status=1 and system_id =:system_id order by sort asc"
        list = MySqlDb.query(sql, params=params)
        #散列成字典
        # menu_dict = {}
        # for item in list:
        #     menu_dict[item["id"]] = item
        #组装树形结构
        menu_tree = []
        temp_dict = {}
        for item in list:
            id = item["id"]
            # 组装新的字典
            tree_item = {
                "id": id,
                "label": item["menu_name"],
                #不展开
                "expanded": False,
            }
            #建立关系使用
            temp_dict[id]=tree_item
            #如果父菜单ID为0，说明是根菜单
            if item["parent_id"] == 0:
                menu_tree.append(tree_item)
            else:
                #如果父菜单ID不为0，说明是子菜单
                parent_menu = temp_dict[item["parent_id"]]
                #子菜单不存在时，创建一个空列表
                if "children" not in parent_menu:
                    parent_menu["children"] = []
                #把子菜单添加到父菜单的children列表中
                parent_menu["children"].append(tree_item)

        return Response(Result(data=menu_tree))


'''更新菜单'''
class MenuUpdate(APIView):
    def post(self, request):
        print("=========== 进入到了MenuUpdate ==========")
        session = None
        try:
            # 请求参数
            params = request.data
            print("请求参数：", params)
            id=params.get("id")
            session = MySqlDb.get_mysql_session()
            menu:Menu = session.query(Menu).filter(Menu.id==id).first()
            if menu:
                #字段parent_id,menu_name,path,icon,sort,permission,menu_type,component,visible,cache,system_id,short_name,remark,status
                menu.parent_id = params.get("parent_id")
                menu.menu_name = params.get("menu_name")
                menu.path = params.get("path")
                menu.icon = params.get("icon")
                menu.sort = params.get("sort")
                menu.permission = params.get("permission")
                menu.menu_type = params.get("menu_type")
                menu.component = params.get("component")
                menu.is_visible = params.get("is_visible")
                menu.is_cache = params.get("is_cache")
                menu.is_leaf = params.get("is_leaf")
                menu.system_id = params.get("system_id")
                menu.short_name = params.get("short_name")
                menu.remark = params.get("remark")
                menu.status = params.get("status")
                menu.update_time = datetime.datetime.now()
                session.commit()
                return Response(Result(data=1))
        except Exception as e:
            print("更新菜单异常：",e)
            if session:
               session.rollback()
            return Response(Result(code=444, msg="更新失败！", data=0))
        finally:
            if  session:
                session.close()


'''菜单新增'''
class MenuAdd(APIView):
    def post(self, request):
        print("=========== 进入到了MenuAdd ==========")
        #请求参数
        params = request.data
        print("请求参数：", params)
        #菜单，组装成对象
        menu = Menu(
            parent_id=params.get("parent_id"),
            menu_name=params.get("menu_name"),
            path=params.get("path"),
            icon=params.get("icon"),
            sort=params.get("sort"),
            permission=params.get("permission"),
            menu_type=params.get("menu_type"),
            component=params.get("component"),
            is_visible=params.get("is_visible"),
            is_cache=params.get("is_cache"),
            is_leaf=params.get("is_leaf"),
            system_id=params.get("system_id"),
            short_name=params.get("short_name"),
            remark=params.get("remark"),
            status=params.get("status"),
            update_date=datetime.datetime.now(),
            create_date=datetime.datetime.now()

        )
        try:
            MySqlDb.insert_by_model(menu)
            return Response(Result(data=1))
        except Exception as e:
            print("新增菜单异常：",e)
            return Response(Result(code=444, msg="新增失败！", data=0))


'''删除菜单'''
class MenuDelete(APIView):
    #get请求
    def get(self, request):
        print("=========== 进入到了MenuDelete ==========")
        #请求参数
        params = request.GET.dict()
        print("请求参数：", params)
        #删除菜单
        try:
            #删除菜单
            sql = "delete from sys_menu where id=:id"
            count = MySqlDb.delete(sql,params=params)
            if count==0:
                return Response(Result(code=444, msg="删除失败！", data=0))
            if count>0:
                return Response(Result(data=1))
        except Exception as e:
            print("删除菜单异常：",e)
            return Response(Result(code=444, msg="删除失败！", data=0))
'''进入角色界面'''
def to_role(request):
    return render(request, "demo/role_page.html")

from common.db_util import MySqlDb

'''角色列表数据，api接口'''
class RoleList(APIView):
    def get(self, request):
        # 获取查询参数
        params = request.GET.dict()
        print("params:",params)
        where_clause = ""
        #用户名称
        role_name = params.get("role_name")
        if role_name:
            where_clause += f" and role_name like '%{role_name}%'"
        #状态信息
        status = params.get("status")
        if status:
            status = int(status)
            if status == -1:
                where_clause += " and status in (0,1)"
            else:
                where_clause += " and status = :status"
        #查询数据库，用户列表数据
        sql = "select * from sys_role where 1=1 "
        #拼接sql
        if where_clause:
            sql += where_clause
        role_list= MySqlDb.query(sql,params)
        #把数据返回到前端
        return Response(Result(data=role_list))


def iterate_tree(menu_tree,array:list):
    for item in menu_tree:
        if item.get("children"):
            iterate_tree(item["children"],array)
        else:
            if (item.get("is_leaf") or item.get("menu_type")==2 ) and item.get("checked"):
                array.append(item["id"])
'''新增角色'''
class RoleAdd(APIView):
    def post(self, request):
        session = None
        try:
            # 获取请求参数
            params = request.data
            print("params:",params)
            # 取出menu_tree
            menu_tree = params.get("menu_tree")
            menu_ids = []
            if menu_tree:
                iterate_tree(menu_tree,menu_ids)

            session = MySqlDb.get_mysql_session()
            # 开始事务
            session.begin()

            # 创建角色
            role = Role(
                role_name=params.get("role_name"),
                role_key=params.get("role_key"),
                sort=params.get("sort"),
                status=params.get("status"),
                remark=params.get("remark"),
                is_deleted=params.get("is_deleted"),
                create_time=datetime.datetime.now(),
                update_time=datetime.datetime.now()
            )
            session.add(role)
            session.flush()  # 刷新以获取ID

            # 插入角色菜单关系
            if menu_ids:
                for menu_id in menu_ids:
                    role_menu = RolePermission(
                        role_id=role.id,
                        menu_id=menu_id
                    )
                    session.add(role_menu)

            session.commit()
            return Response(Result(data=1))

        except Exception as e:
            print(e)
            if session:
                session.rollback()
            return Response(Result(code=444,msg="新增失败！==>"+str(e),data=0))
        finally:
            if session:
                session.close()


'''角色信息修改'''
class RoleModify(APIView):
    def post(self, request):
        print("=========== 进入到了RoleModify ==========")
        # 获取请求参数
        params = request.data
        print("params:",params)
        role:Role = Role()
        #取出前端传来的参数：role_id,role_name,role_key,sort,status,description,is_deleted,create_time,update_time
        role.id = params.get("id")
        menu_ids = params.get("menu_ids")     # 取出menu_tree
        menu_tree = params.get("menu_tree")
        menu_ids = []
        if menu_tree:
           iterate_tree(menu_tree,menu_ids)

        session = MySqlDb.get_mysql_session()
        try:
            #查询出用户信息
            role:Role = session.query(Role).filter(Role.id==params.get("id")).first()
            if role:
                #更新用户信息
                role.role_name = params.get("role_name")
                role.role_key = params.get("role_key")
                role.sort = params.get("sort")
                role.status = params.get("status")
                role.remark = params.get("remark")
                role.is_deleted = params.get("is_deleted")
                role.update_time = datetime.datetime.now()
                session.commit()

                #删除角色菜单关系
                sql = "delete from sys_role_permission where role_id=:role_id"
                MySqlDb.delete(sql,params={"role_id":role.id})
                #插入角色菜单关系
                if menu_ids:
                    for menu_id in menu_ids:
                        role_menu = RolePermission(
                            role_id=role.id,
                            menu_id=menu_id
                        )
                        session.add(role_menu)
                        session.commit()

                return Response(Result(data=1))
        except Exception as e:
            print(e)
            session.rollback()
            return Response(Result(code=444,msg="更新失败！==>"+e.__str__(),data=0))
        finally:
            if session:
                session.close()

'''删除角色'''
class RoleDelete(APIView):
    def get(self, request):
        # 获取请求参数
        params = request.GET.dict()
        print("params:",params)
        id = params.get("id")
        #sql删除，物理删除
        sql = "delete from sys_role where id = :id"
        result = MySqlDb.delete(sql,params)
        # 删除角色菜单关系
        sql = "delete from sys_role_permission where role_id=:role_id"
        MySqlDb.delete(sql, params={"role_id": id})
        if result:
            return Response(Result(data=1))
        else:
            return Response(Result(code=444,msg="删除失败！",data=0))

'''批量删除用户'''
class RoleDeleteBatch(APIView):
    def post(self, request):
        # 获取请求参数
        params = request.data
        print("params:",params)
        ids = params.get("ids")
        ids_str = ""
        for id in ids:
            ids_str += f"{id},"
        #去掉最后一个逗号
        ids_str = ids_str[:-1]
        params = {
            "ids":ids_str
        }
        #sql删除，物理删除
        sql = "delete from sys_role where id in (:ids)"
        result = MySqlDb.delete(sql,params)
        # 删除角色菜单关系
        sql = "delete from sys_role_permission where role_id in(:ids)"
        MySqlDb.delete(sql, params={"role_id": ids})
        if result:
            return Response(Result(data=1))
        else:
            return Response(Result(code=444,msg="删除失败！",data=0))

'''查询角色授权限树'''
class RoleSelectTree(APIView):
    def get(self, request):
        print("=========== 进入到了RoleSelectTree ==========")
        # 获取请求参数
        params = request.GET.dict()
        print("params:",params)
        role_id = params.get("role_id")
        role_menu_dict = {}
        if role_id:
            #查询出角色对应的菜单ID
            sql = "select menu_id from sys_role_permission where role_id = :role_id"
            role_menu_list = MySqlDb.query(sql,params)
            for item in role_menu_list:
                role_menu_dict[item["menu_id"]] = item["menu_id"]


        #先查询出子系统
        sql = "select * from sys_sub_system where status=1 order by sort asc"
        system_list = MySqlDb.query(sql,params)
        #查询子系统对应的菜单
        my_systems=[]
        for system in system_list:
            params = {
                "system_id":system["id"]
            }
            sql = "select * from sys_menu where status=1 and system_id =:system_id order by sort asc"
            menu_list = MySqlDb.query(sql,params)
            #组装菜单树
            temp_dict={}
            for menu in menu_list:
                id = menu["id"]
                temp_dict[id]=menu
                menu["label"] = menu["menu_name"]
                menu["expanded"] = False
                #如果菜单id在角色菜单字典中，说明角色有该菜单权限
                if role_menu_dict.get(id):
                    menu["checked"] = True
                else:
                    menu["checked"] = False
            #组装菜单
            menu_tree = []
            for menu in menu_list:
                #如果父菜单ID为0，说明是根菜单
                if menu["parent_id"] == 0:
                    menu_tree.append(menu)
                else:
                    #如果父菜单ID不为0，说明是子菜单
                    parent_menu = temp_dict[menu["parent_id"]]
                    #子菜单不存在时，创建一个空列表
                    if "children" not in parent_menu:
                        parent_menu["children"] = []
                    #把子菜单添加到父菜单的children列表中
                    parent_menu["children"].append(menu)

            #子系统对应的菜单树
            my_systems.append({
                "id":system["id"],
                "label":system["sub_short_name"],
                "expanded":True,
                "system_name":system["system_name"],
                "children":menu_tree
            })
        return Response(Result(data=my_systems))

'''用户菜单树'''
class UserMenuTree(APIView):
    def get(self, request):
        print("=========== 进入到了UserMenuTree ==========")
        # 获取请求参数
        params = request.GET.dict()
        print("params:",params)
        #取出用户会话信息

        user:User = request.session.get("user_info")
        username = user.get("username")
        '''超级管理员，可以查询所有菜单（特殊处理）'''
        if username == 'admin':
            all_menu_tree = get_all_menu_tree()
            return Response(Result(data=all_menu_tree))

        user_id = None
        if user:
            user_id = user.get("id")
        else:
            user_id = params.get("user_id")

        #查询出菜单表数据
        sql = "select * from sys_menu where status=1"
        menu_list = MySqlDb.query(sql)
        #转换成字典
        menu_dict = {}
        for item in menu_list:
            menu_dict[item["id"]] = item

        #查询菜单树
        sql = '''  select
                    distinct t3.*
                    from
                        sys_user_role t1
                    left join sys_role_permission t2 on
                        t1.role_id = t2.role_id
                    left join sys_menu t3 on
                        t2.menu_id = t3.id
                    where t1.user_id = :user_id
	          '''
        params = {
            "user_id":user_id
        }
        #查询出叶子授权树
        menu_leaf_list = MySqlDb.query(sql,params)
        #根据查询出来的叶子授权树，组装成菜单树
        temp_dict={}
        #组装菜单树
        for item in menu_leaf_list:
            #如果父菜单ID为0，说明是根菜单
            iterate_menu_tree(item,menu_dict,temp_dict)
        print("筛选父子级关系后的数据：", temp_dict)
        my_menu_tree = []
        for key,item in temp_dict.items():
            #如果父菜单ID为0，说明是根菜单
             if item.get("parent_id") == 0:
                 my_menu_tree.append(item)
                 print("key:",key)
        return Response(Result(data=my_menu_tree))

def iterate_menu_tree(node,menu_dict,temp_dict):
    parent_id = node["parent_id"]
    if parent_id == 0:
        #说明是根菜单
        top_parent = temp_dict.get(node["id"])
        if not top_parent:
            temp_dict[node["id"]] = {
                "id":node["id"],
                "parent_id":0,
                "title":node["menu_name"],
                "icon": node["icon"],
                "url": node.get("path"),
                "children":[]
            }
        else:
            #补充顶级的parent_id，后续筛选需要
            top_parent["parent_id"] = 0
        return
    else:
        parent_node = menu_dict[parent_id]
        temp_parent_node = temp_dict.get(parent_id)
        #创建级组装的父节点
        if not temp_parent_node:
            temp_parent_node = {
                "id":parent_node["id"],
                "title":parent_node["menu_name"],
                "icon": parent_node["icon"],
                "url": parent_node.get("path"),
                "children":[]
            }
            temp_dict[parent_id] = temp_parent_node
        # 当前节点不是叶子

        if  node["is_leaf"] != 1:
            #temp_menu_dict是否存在当前节点
            if not temp_dict.get(node["id"]):
                temp_dict[node["id"]] = {
                    "id":node["id"],
                    "title":node["menu_name"],
                    "icon": node["icon"],
                    "url": node.get("path"),
                    "children":[]
                }
            #把当前节点添加到父节点的children列表中(注意去重)
            if not temp_dict[node["id"]] in temp_parent_node["children"]:
                temp_parent_node["children"].append(temp_dict[node["id"]])
        #不是顶级路子叶子节点，继续遍历
        iterate_menu_tree(parent_node,menu_dict,temp_dict)

'''查询超级管理菜单树（所有）'''
def get_all_menu_tree():
    # 根据系统ID查询菜单列表
    sql = "select id,menu_name,parent_id,icon,path from sys_menu sm where sm.status=1 and is_leaf != 1 order by sort asc"
    list = MySqlDb.query(sql)
    # 散列成字典
    menu_dict = {}
    for item in list:
        menu_dict[item["id"]] = item
    # 组装树形结构
    menu_tree = []
    for item in list:
        item["title"] = item["menu_name"]
        item["icon"] = item["icon"]
        item["url"] = item.get("path")
        # 如果父菜单ID为0，说明是根菜单
        if item["parent_id"] == 0:
            menu_tree.append(item)
        else:
            # 如果父菜单ID不为0，说明是子菜单
            parent_menu = menu_dict[item["parent_id"]]
            # 子菜单不存在时，创建一个空列表
            if "children" not in parent_menu:
                parent_menu["children"] = []
            # 把子菜单添加到父菜单的children列表中
            parent_menu["children"].append(item)
    return menu_tree





